package com.luobd.bpm.controller;

import cn.hutool.core.util.StrUtil;
import com.luobd.bpm.common.PageInput;
import com.luobd.bpm.common.ResponsePageData;
import com.luobd.bpm.dto.ProcessDefinitionDTO;
import com.luobd.bpm.input.ProcessDeploymentInput;
import com.luobd.bpm.input.ProcessDeploymentStringInput;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/api/bpmn/repository")
@Api(tags = "流程定义管理")
public class BpmnRepositoryController {


    @Autowired
    private RepositoryService repositoryService;



    @PostMapping(value = "/deleteProcessDefinition")
    @ApiOperation(value = "删除流程定义")
    public String deleteProcessDefinition(@RequestBody ProcessDeleteInput input) {

        if(StrUtil.isNotEmpty(input.getDeploymentId())) {
            repositoryService.deleteDeployment(input.getDeploymentId(), input.isCascade());
        } else if (StrUtil.isNotEmpty(input.getProcessDefinitionId())){
            ProcessDefinition definition = repositoryService.getProcessDefinition(input.getProcessDefinitionId());
            if(definition != null) {
                repositoryService.deleteDeployment(definition.getDeploymentId(), input.isCascade());
            }else {
                return "流程定义不存在";
            }
        }else {
            return "流程部署id和流程定义id必传其中一个";
        }
        return "success";
    }


    @PostMapping(value = "/deploymentByString")
    @ApiOperation(value = "部署流程定义 - 通过xml字符串")
    public String deployment(@RequestBody(required = false) ProcessDeploymentStringInput input) {

        return repositoryService.createDeployment()
                .name(input.getName())
                .category(input.getCategory())
                .addString(input.getResourceName(), input.getBpmnXml())
                .deploy().getId();
    }

    @PostMapping(value = "/deploymentByResource")
    @ApiOperation(value = "部署流程定义 - 通过资源路径")
    public String deployment(@RequestBody ProcessDeploymentInput input) {
        return repositoryService.createDeployment()
                .name(input.getName())
                .category(input.getCategory())
                .addClasspathResource(input.getResourceName())
                .deploy().getId();
    }


    @GetMapping(value = "/allDefinitions")
    @ApiOperation(value = "获取所有流程定义")
    public List<ProcessDefinitionDTO> getAllProcessDefinitions() {
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
        return list.stream().map(ProcessDefinitionDTO::new).collect(Collectors.toList());
    }


    @PostMapping(value = "/page")
    @ApiOperation(value = "分页查询流程定义")
    public ResponsePageData<ProcessDefinitionDTO> page(@RequestBody PageQueryInput input) {
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        if(StrUtil.isNotEmpty(input.getName())) {
            query.processDefinitionNameLike(input.getName() + "%");
        }
        if(StrUtil.isNotEmpty(input.getCategory())) {
            query.processDefinitionCategory(input.getCategory());
        }
        if(StrUtil.isNotEmpty(input.getKey())) {
            query.processDefinitionKeyLike(input.getKey() + "%");
        }
        return ResponsePageData.success(query.listPage(input.getStart(),input.getPageSize())
                .stream().map(ProcessDefinitionDTO::new).collect(Collectors.toList()),query.count());
    }



}


@ApiModel(description = "删除流程定义")
@Data
class ProcessDeleteInput {

    /**
     * <span>流程定义、流程部署信息，流程定义数据，资源数据会被删除</span>
     */
    @ApiModelProperty(value = "流程部署id")
    private String deploymentId;

    @ApiModelProperty(value = "流程定义id")
    private String processDefinitionId;

    /**
     * <span>级联删除会同时删除流程定义下的流程实例，job等</span>
     */
    @ApiModelProperty(value = "是否级联删除")
    private boolean cascade;
}


@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "分页查询流程定义")
class PageQueryInput extends PageInput {

    @ApiModelProperty(value = "流程定义key")
    private String key;

    @ApiModelProperty(value = "流程定义分类")
    private String category;

    @ApiModelProperty(value = "流程定义名称")
    private String name;
}




